﻿// MIT License
// 开源地址：https://gitee.com/co1024/AbcMvc
// Copyright (c) 2021-2023 1024
// Abc.Mvc=Furion+EF+SqlSugar+Pear layui admin.

namespace Abc.Application;

/// <summary>
/// 数据配置
/// </summary>
public class DataConfigService : IDataConfigService, ITransient
{
    private readonly ILogger<DataConfigService> _logger;
    private readonly ISqlSugarClient _db;

    public DataConfigService(ILogger<DataConfigService> logger
     , ISqlSugarClient db = null)
    {
        _logger = logger;
        _db = db;
    }

    /// <summary>
    /// 新增或更新一条
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task InsertOrUpdate(DataConfigInput input)
    {
        if (string.IsNullOrWhiteSpace(input.PKey))
        {
            input.PKey = "";
        }
        if (input.Id > 0)
        {
            //验证 父级下 唯一 Key是否存在
            var isexit = await _db.Queryable<SysDataConfig>().AnyAsync(o => o.PKey == input.PKey && o.Key == input.Key && o.Id != input.Id);
            if (isexit)
            {
                throw Oops.Bah("唯一标识Key不能重复");
            }
            var dbentity = await _db.Queryable<SysDataConfig>().FirstAsync(o => o.Id == input.Id.Value);
            input.Adapt(dbentity);
            await _db.UpdateAsync(dbentity);
        }
        else
        {
            //验证 父级下 唯一 Key是否存在
            var isexit = await _db.Queryable<SysDataConfig>().AnyAsync(o => o.PKey == input.PKey && o.Key == input.Key);
            if (isexit)
            {
                throw Oops.Bah("唯一标识Key不能重复");
            }
            var addentity = input.Adapt<SysDataConfig>();
            var newEntity = await _db.InsertRsIdAsync<SysDataConfig>(addentity);
        }
    }

    /// <summary>
    /// 删除一条
    /// </summary>
    /// <param name="id"></param>
    public async Task Delete(long id)
    {
        if (id <= 0) throw Oops.Bah("id不能为0");
        await _db.DeleteByIdAsync<SysDataConfig>(id);
    }

    /// <summary>
    /// 批量删除
    /// </summary>
    /// <param name="ids">需要删除的数据，多条以英文逗号隔开</param>
    public async Task BatchDelete(string ids)
    {
        await _db.FakeDeleteAsync<SysDataConfig>(ids);
    }

    /// <summary>
    /// 查询所有
    /// </summary>
    /// <returns></returns>
    public List<DataConfigOut> GetAll()
    {
        return _db.Queryable<SysDataConfig>().ToList().Adapt<List<DataConfigOut>>();
    }

    /// <summary>
    /// 查询一条
    /// </summary>
    /// <param name="id"></param>
    public async Task<TEntity> Get<TEntity>(long id)
    {
        var dbentity = await _db.Queryable<SysDataConfig>().FirstAsync(o => o.Id == id);
        if (dbentity == null) return default(TEntity);
        return dbentity.Adapt<TEntity>();
    }

    /// <summary>
    /// 查询一条
    /// </summary>
    /// <param name="key"></param>
    public async Task<DataConfigOut> GetByKey(string key)
    {
        var dbentity = await _db.Queryable<SysDataConfig>().FirstAsync(o => !string.IsNullOrWhiteSpace(o.Key) && o.Key.ToLower().Trim() == key.ToLower().Trim());
        if (dbentity == null) return null;
        return dbentity.Adapt<DataConfigOut>();
    }

    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="searchQuery"></param>
    /// <returns></returns>
    public async Task<LayuiPagedList<DataConfigOut>> GetAllByPageToLayui(DataConfigQuery searchQuery)
    {
        var queryable = _db.Queryable<SysDataConfig>();
        if (!string.IsNullOrWhiteSpace(searchQuery.KeyWords))
        {
            var kw = searchQuery.KeyWords.ToLower();
            queryable = queryable.Where(o => o.Key.Contains(kw));
        }

        var pageResult = queryable.OrderByDescending(o => o.Id);
        var pagedlist = await pageResult.ToLayuiPagedListAsync<SysDataConfig, DataConfigOut>(searchQuery.Page, searchQuery.Limit);

        //var entities = await _cacheService.GetDataConfigEntities();
        //return await _repository.Adapt<List<DataConfigOut>>().ToLayuiPagedListAsync(searchQuery.Page, searchQuery.Limit);

        pagedlist.data = HandleChildren(pagedlist.data);

        return pagedlist;
    }

    private List<DataConfigOut> HandleChildren(IEnumerable<DataConfigOut> menus, string pKey = "")
    {
        List<DataConfigOut> menuItems = new List<DataConfigOut>();
        foreach (var menuitem in menus.Where(o => o.PKey != null && o.PKey.ToLower() == pKey.ToLower()).OrderBy(o => o.Sort))
        {
            if (!string.IsNullOrWhiteSpace(menuitem.Key) && menus.Any(o => o.PKey != null && o.PKey.ToLower() == pKey.ToLower()))
            {
                menuitem.children = HandleChildren(menus, menuitem.Key);
            }
            menuitem.IsParent = !string.IsNullOrWhiteSpace(pKey);
            menuItems.Add(menuitem);
        }

        return menuItems;
    }

    #region 查询下拉树

    /// <summary>
    /// 查询菜单下来树
    /// </summary>
    /// <returns></returns>
    public async Task<Dtree> GetDtree(string pid = "")
    {
        var dataconfigs = await _db.Queryable<SysDataConfig>().ToListAsync(o => new DtreeEntity { id = o.Key, pid = o.PKey, name = o.Name, sort = o.Sort });
        var dtree = dataconfigs.GetDtree(pid = "");
        return dtree;
    }

    #endregion 查询下拉树

    /// <summary>
    /// 获取系统设置
    /// </summary>
    /// <returns></returns>
    public async Task<TEntity> GetSetting<TEntity>(long pid) where TEntity : new()
    {
        //var entities = await _cacheService.GetDataConfigEntities();
        var settings = await _db.Queryable<SysDataConfig>().Where(o => o.PId == pid).ToListAsync();
        var settingdto = new TEntity();
        foreach (var setting in settings)
        {
            settingdto.FieldSetValue(setting.Key, setting.Value);
        }
        return settingdto;
    }

    /// <summary>
    /// 获取系统设置
    /// </summary>
    /// <returns></returns>
    public async Task<TEntity> GetSetting<TEntity>(string pkey) where TEntity : new()
    {
        //var entities = await _cacheService.GetDataConfigEntities();
        var settings = await _db.Queryable<SysDataConfig>().Where(o => o.PKey == pkey).ToListAsync();
        var settingdto = new TEntity();
        foreach (var setting in settings)
        {
            settingdto.FieldSetValue(setting.Key, setting.Value);
        }
        return settingdto;
    }

    /// <summary>
    /// 新增或修改设置
    /// </summary>
    /// <param name="input">输入对象</param>
    /// <param name="pkey">父级</param>
    /// <returns></returns>
    public async Task AddOrUpdateSetting(object input, string pkey)
    {
        var dataconfigs = await _db.Queryable<SysDataConfig>().Where(o => o.PKey == pkey).ToListAsync();

        //var pdataconfig = await Entities.FirstOrDefaultAsync(o => o.Key == pkey);
        var updateDataConfigs = new List<SysDataConfig>();
        var propertys = input.GetDictionaryEntityInfo();
        foreach (var property in propertys)
        {
            var dataconfig = dataconfigs.FirstOrDefault(o => o.Key != null && o.Key == property.Key && o.PKey == pkey);
            if (dataconfig == null)
            {
                //不存在，创建一个新的配置
                var newdataconfig = new SysDataConfig
                {
                    //PId = pdataconfig.Id,
                    PKey = pkey,
                    Key = property.Key,
                    //Value = property.Value.GetValue("Value"),
                    //Name = property.Value.GetValue("Description"),
                    Value = property.Value.Value,
                    Name = property.Value.Description,
                    IsEnable = true
                };
                var rnewdataconfig = await _db.InsertRsIdAsync<SysDataConfig>(newdataconfig);
            }
            else
            {
                dataconfig = await _db.Queryable<SysDataConfig>().FirstAsync(o => o.Key != null && o.Key == dataconfig.Key && o.PKey == pkey);
                dataconfig.Value = property.Value.Value;//值
                dataconfig.Name = property.Value.Description;//名称

                updateDataConfigs.Add(dataconfig);
            }
        }
        await _db.Updateable(updateDataConfigs).ExecuteCommandAsync();
    }

    /// <summary>
    /// 设置状态
    /// </summary>
    /// <param name="id"></param>
    /// <param name="state"></param>
    /// <param name="field">字段名</param>
    /// <returns></returns>
    public async Task SetState(long id, bool state, string field)
    {
        var result = await _db.SetStateByIdAsync<SysRole>(id, state, field);
    }
}